package com.zanbo.clock.service.impl;

import com.zanbo.clock.domain.entity.Clock;
import com.zanbo.clock.domain.entity.Staff;
import com.zanbo.clock.domain.mapper.ClockMapper;
import com.zanbo.clock.domain.mapper.StaffMapper;
import com.zanbo.clock.exception.ServiceException;
import com.zanbo.clock.model.base.out.ClockInfo;
import com.zanbo.clock.model.code.BaseCodeInterface;
import com.zanbo.clock.model.code.ErrorCode;
import com.zanbo.clock.service.ClockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.GregorianCalendar;

/**
 * @author: zanbo
 * @description: 签到service层
 * @date: 上午 11:03 2021-4-26
 */
@Service
//@SuppressWarnings({"all"})
public class ClockServiceImpl implements ClockService {
    
    @Autowired
    private StaffMapper staffMapper;
    
    @Autowired
    private ClockMapper clockMapper;
    
    private final static GregorianCalendar ggC = new GregorianCalendar();
    
    /**
     * @author: zanbo
     * @description: 签到service
     * @date: 上午 10:58 2021-4-26
     * @params [uid]
     * @return com.zanbo.clock.model.base.out.ClockInfo
     */
    @Override
    public ClockInfo doClock(Long uid) {
        //对当前时间进行判断
        if (ggC.get(GregorianCalendar.AM_PM) == 0) {
            //当前时间为上午，传入约束为上午的三个参数和员工id
            return handle(uid,LocalTime.MIN,LocalTime.NOON,ErrorCode.CLOCK_AM_AGAIN);
        } else {
            //当前时间为下午，如果当天上午没有他的签到记录则不可签退
            Staff staff = staffMapper.selectOne(new Staff(null, uid, null, null));
            Example example = new Example(Clock.class);
            Example.Criteria criteria = example.createCriteria();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            if (staff == null) {
                throw new ServiceException(ErrorCode.NOT_USERNAME);
            }
            criteria.andEqualTo("uid", uid);
            criteria.andGreaterThanOrEqualTo("cdate", LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MIN).format(formatter));
            criteria.andLessThanOrEqualTo("cdate", LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.NOON).format(formatter));
            Clock info = clockMapper.selectOneByExample(example);
            if (info == null) {
                //不可签到，直接抛出异常
                throw new ServiceException(ErrorCode.NO_CLOCK);
            }
            //传入约束为下午的三个参数和员工id
            return handle(uid,LocalTime.NOON,LocalTime.MAX,ErrorCode.CLOCK_PM_AGAIN);
        }
    }
    
    /**
     * @author zanbo
     * @description 用通用mapper进行范例查询
     * @date 上午 11:36 2021-4-26
     * @params [uid, first, last, e]
     * @return com.zanbo.clock.model.base.out.ClockInfo
     */
    public ClockInfo handle(Long uid, LocalTime first, LocalTime last, BaseCodeInterface e) {
        Staff staff = staffMapper.selectOne(new Staff(null, uid, null, null));
        Example example = new Example(Clock.class);
        Example.Criteria criteria = example.createCriteria();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if (staff == null) {
            //如果没有该员工抛出异常
            throw new ServiceException(ErrorCode.NOT_USERNAME);
        }
        criteria.andEqualTo("uid", uid);
        criteria.andGreaterThanOrEqualTo("cdate", LocalDateTime.of(LocalDateTime.now().toLocalDate(), first).format(formatter));
        criteria.andLessThanOrEqualTo("cdate", LocalDateTime.of(LocalDateTime.now().toLocalDate(), last).format(formatter));
        Clock info = clockMapper.selectOneByExample(example);
        ClockInfo clockInfo = new ClockInfo();
        clockInfo.setUid(uid);
        clockInfo.setUname(staff.getUname());
        if (info != null) {
            //这个时间段已经打过卡了，跳到最后抛出异常
            clockInfo.setCTime(info.getCdate().toInstant(ZoneOffset.ofHours(8)).toEpochMilli()+"");
        }
        if (info == null) {
            Clock clock = new Clock();
            clock.setUid(uid);
            clock.setCdate(LocalDateTime.now());
            int insert = clockMapper.insert(clock);
            if (insert == 0) {
                throw new ServiceException(ErrorCode.CLOCK_ERROR);
            }
            clockInfo.setCTime(LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli()+"");
            //签到成功，返回信息
            return clockInfo;
        }
        throw new ServiceException(e, clockInfo);
    }
    
}
